package com.example.Windturbine.Controller;

import com.example.Windturbine.Controller.ViewObject.ResultGraphVO.ResultMetaVO;
import com.example.Windturbine.Controller.ViewObject.ResultGraphVO.ResultNode;
import com.example.Windturbine.Controller.ViewObject.ResultGraphVO.ResultRelation;
import com.example.Windturbine.Controller.ViewObject.ResultVO.*;
import com.example.Windturbine.Dao.ProductResultDOMapper;
import com.example.Windturbine.DataObject.ProductResultDO;
import com.example.Windturbine.Error.BusinessException;
import com.example.Windturbine.Response.CommonResult;
import com.example.Windturbine.Service.PartResultService;
import com.example.Windturbine.Service.ProductCalService;
import com.example.Windturbine.Service.ProductResultService;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.PriorityQueue;

/**
 * @Author 丁永新
 * @Date 2021/12/23
 */
@Slf4j
@Controller("result")
@RequestMapping("/result")
@CrossOrigin(allowCredentials = "true", allowedHeaders = "*")
public class ResultController {

    @Autowired
    ProductResultService productResultService;

    @Autowired
    PartResultService partResultService;

    @Autowired
    ProductCalService productCalService;

    /**
     * 获取列表详情
     *
     * @param calid
     * @param productid
     * @return
     */
    @RequestMapping("/getlist")
    @ResponseBody
    public CommonResult getList(@RequestParam(name = "calid") Integer calid, @RequestParam(name = "productid") Integer productid) throws BusinessException {
        List<ListResultVO> list = new ArrayList<>();
        ListResultVO product = productResultService.getResult(calid, productid);
        List<ListResultVO> parts = partResultService.getResult(calid, productid);
        list.add(product);
        for (int j = 1; j <= 6; j++) {
            for (ListResultVO i : parts) {
                String type = i.getType();
                String[] aa = type.split(" ");
                if (Integer.parseInt(aa[0]) == j) list.add(i);
            }
        }

        return CommonResult.create(list);
    }


    @RequestMapping("/delete")
    @ResponseBody
    public CommonResult delete(@RequestParam(name = "calid") Integer calid, @RequestParam(name = "productid") Integer productid) throws BusinessException {

        productCalService.deleteById(calid);
        return CommonResult.create(null);
    }


    @RequestMapping("/getgraphlist")
    @ResponseBody
    public CommonResult getGraphList(@RequestParam(name = "calid") Integer calid, @RequestParam(name = "productid") Integer productid) throws BusinessException {

        //获取第一张的图的数据
        ProductGraphVO graphResult = productResultService.getGraphResult(calid, productid);
        //获取第二张的图的数据
        List<PartGraphVO> graphPart = partResultService.getGraphResult(calid, productid);


        PartGraphVO2 partGraphVO2 = convertFromPartGraphVO(graphPart);


        //获取第三张绿色度饼图数据
        List<ListResultVO> list = new ArrayList<>();
        ListResultVO product = productResultService.getResult(calid, productid);
        List<ListResultVO> parts = partResultService.getResult(calid, productid);
        list.add(product);
        for (int j = 1; j <= 6; j++) {
            for (ListResultVO i : parts) {
                String type = i.getType();
                String[] aa = type.split(" ");
                if (Integer.parseInt(aa[0]) == j) list.add(i);
            }
        }

        List<String> names = new ArrayList<>();//pie1
        List<PieValueVO> pie1 = new ArrayList<>();
        List<PieValueVO> pie2 = new ArrayList<>();
        List<PieValueVO> pie3 = new ArrayList<>();

        //对pie1进行排序
        PriorityQueue<PieValueVO> pie1queue=new PriorityQueue<PieValueVO>((a,b)->{
            return a.getValue().compareTo(b.getValue());
        });

        //对pie2进行排序
        PriorityQueue<PieValueVO> pie2queue=new PriorityQueue<PieValueVO>((a,b)->{
            return b.getValue().compareTo(a.getValue());
        });
        BigDecimal total2=new BigDecimal(0);
        for (int i = 0; i < parts.size(); i++) {
            ListResultVO listResultVO = parts.get(i);
            names.add(listResultVO.getName());
            String type = listResultVO.getType();
            String[] aa = type.split(" ");
            PieValueVO p = new PieValueVO(listResultVO.getGreenvalue(), listResultVO.getName());
            if (Integer.parseInt(aa[0]) == 1) {
                pie1.add(p);
                pie1queue.offer(p);
            } else if ((Integer.parseInt(aa[0]) == 2)) {
                pie2.add(p);
                total2=total2.add(p.getValue());
                pie2queue.offer(p);
            } else if ((Integer.parseInt(aa[0]) == 10)) {
                pie3.add(p);
            }
        }


        pie1=new ArrayList<>();
        while(!pie1queue.isEmpty()){
            pie1.add(pie1queue.poll());
        }




        pie2=new ArrayList<>();
        while(!pie2queue.isEmpty()){
            PieValueVO poll = pie2queue.poll();
            BigDecimal divide = poll.getValue().divide(total2, 2, BigDecimal.ROUND_HALF_DOWN);
            if(divide.doubleValue()>=0.01) pie2.add(poll);
        }



        PieResultVO pieResultVO = new PieResultVO(names, pie1, pie2, pie3);


        return CommonResult.create(new ResultGraphListVO(graphResult, partGraphVO2, pieResultVO));
    }


    /**
     * 获取多域关联的数据
     *
     * @param calid
     * @param productid
     * @return
     * @throws BusinessException
     */
    @RequestMapping("/getmeta")
    @ResponseBody
    public CommonResult getMeta(@RequestParam(name = "calid") Integer calid, @RequestParam(name = "productid") Integer productid) throws BusinessException {

        List<ResultRelation> relations = new ArrayList<>();
        List<BigDecimal> nodesize = new ArrayList<>();
        ResultNode metaResult = productResultService.getMetaResult(calid, productid);
        List<ResultNode> metaResult1 = partResultService.getMetaResult(calid, productid);
        for (ResultNode i : metaResult1) {
            ResultRelation temp = new ResultRelation();
            String orderInfo = i.getOrderInfo();
            Integer num = orderInfo.split("\\.").length;
            if (num == 1) {
                temp.setParent("产品");
                temp.setChild(orderInfo);
                temp.setDes(num + "级零件");
                temp.setName(num + "级零件");
            } else {
                //获取orderinfo的前级order
                temp.setParent(getParent(orderInfo));
                temp.setChild(orderInfo);
                temp.setDes(num + "级零件");
                temp.setName(num + "级零件");
            }
            relations.add(temp);
        }


        BigDecimal d1 = metaResult1.get(0).getGreenvalue();
        BigDecimal d2 = metaResult1.get(0).getRaw();
        BigDecimal d3 = metaResult1.get(0).getPro_transport();
        BigDecimal d4 = metaResult1.get(0).getManufacture();
        BigDecimal d5 = metaResult1.get(0).getRecycle();
        BigDecimal d11 = metaResult1.get(0).getGreenvalue();
        BigDecimal d22 = metaResult1.get(0).getRaw();
        BigDecimal d33 = metaResult1.get(0).getPro_transport();
        BigDecimal d44 = metaResult1.get(0).getManufacture();
        BigDecimal d55 = metaResult1.get(0).getRecycle();
        //计算绿色度的插值
        for (ResultNode r : metaResult1) {
            if (r.getGreenvalue().compareTo(d1) == -1) {
                d1 = r.getGreenvalue();
            }
            if (r.getGreenvalue().compareTo(d11) == 1) {
                d11 = r.getGreenvalue();
            }

            if (r.getRaw().compareTo(d2) == -1) {
                d2 = r.getRaw();
            }
            if (r.getRaw().compareTo(d22) == 1) {
                d22 = r.getRaw();
            }

            if (r.getPro_transport().compareTo(d3) == -1) {
                d3 = r.getPro_transport();
            }
            if (r.getPro_transport().compareTo(d33) == 1) {
                d33 = r.getPro_transport();
            }

            if (r.getManufacture().compareTo(d4) == -1) {
                d4 = r.getManufacture();
            }
            if (r.getManufacture().compareTo(d44) == 1) {
                d44 = r.getManufacture();
            }

            if (r.getRecycle().compareTo(d5) == -1) {
                d5 = r.getRecycle();
            }
            if (r.getRecycle().compareTo(d55) == 1) {
                d55 = r.getRecycle();
            }

        }
        nodesize.add(d11.subtract(d1));
        nodesize.add(d22.subtract(d2));
        nodesize.add(d33.subtract(d3));
        nodesize.add(d44.subtract(d4));
        nodesize.add(d55.subtract(d5));

/*        BigDecimal F=new BigDecimal(1);
        BigDecimal S=new BigDecimal(1);
        BigDecimal M=new BigDecimal(1);
        BigDecimal P=new BigDecimal(1);
        BigDecimal T=new BigDecimal(1);
        BigDecimal GREEN=new BigDecimal(1);
        //先计算出来各个域最大的值
        for (ResultNode n : metaResult1) {
            GREEN=GREEN.max(n.getGreenvalue());
            F=F.max(n.getPro_use());
            S=S.max(n.getRecycle());
            M=M.max(n.getRaw());
            P=P.max(n.getManufacture());
            T=T.max(n.getPro_transport());
        }*/


        //设置结点的等级
        for (ResultNode n : metaResult1) {
            BigDecimal green = (n.getGreenvalue().subtract(d1)).multiply(new BigDecimal(10).divide(nodesize.get(0), 20, BigDecimal.ROUND_HALF_DOWN));
            BigDecimal raw = (n.getRaw().subtract(d2)).multiply(new BigDecimal(10).divide(nodesize.get(1), 20, BigDecimal.ROUND_HALF_DOWN));
            BigDecimal tran = (n.getPro_transport().subtract(d3)).multiply(new BigDecimal(10).divide(nodesize.get(2), 20, BigDecimal.ROUND_HALF_DOWN));
            BigDecimal man = (n.getManufacture().subtract(d4)).multiply(new BigDecimal(10).divide(nodesize.get(3), 20, BigDecimal.ROUND_HALF_DOWN));
            BigDecimal recycle = (n.getRecycle().subtract(d5)).multiply(new BigDecimal(10).divide(nodesize.get(4), 20, BigDecimal.ROUND_HALF_DOWN));

            n.setL1(11 - green.intValue());
            n.setL2(11 - raw.intValue());
            n.setL3(11 - tran.intValue());
            n.setL4(11 - man.intValue());
            n.setL5(11 - recycle.intValue());
        }
        metaResult.setL1(0);
        metaResult.setL2(0);
        metaResult.setL3(0);
        metaResult.setL4(0);
        metaResult.setL5(0);
        metaResult1.add(metaResult);
        ResultMetaVO res = new ResultMetaVO(metaResult1, relations);
        return CommonResult.create(res);
    }


    private PartGraphVO2 convertFromPartGraphVO(List<PartGraphVO> graphPart) {
        //对其进行排序
        List<PartGraphVO> sorted = new ArrayList<>();


        for (int i = 1; i <= 2; i++) {
            for (PartGraphVO j : graphPart) {
                String name = j.getName();
                String[] names = name.split(" ");
                Integer num = Integer.parseInt(names[0]);
                if (num == i) sorted.add(j);
            }
        }


        PartGraphVO2 partGraphVO2 = new PartGraphVO2();
        partGraphVO2.setName(new ArrayList<>());
        partGraphVO2.setData1(new ArrayList<>());
        partGraphVO2.setData2(new ArrayList<>());
        partGraphVO2.setData3(new ArrayList<>());
        partGraphVO2.setData4(new ArrayList<>());
        partGraphVO2.setData5(new ArrayList<>());
        partGraphVO2.setData6(new ArrayList<>());

        PriorityQueue<SortGraphVO> queue = new PriorityQueue<SortGraphVO>((a, b) -> {
            return b.value.compareTo(a.value);
        });


        for (PartGraphVO i : sorted) {
            //计算不同阶段的影响总和
            BigDecimal ped = i.getRaw().getPed().add(i.getManufacture().getPed()).add(i.getPro_transport().getPed()).add(i.getPro_recycle().getPed());
            BigDecimal gwp = i.getRaw().getGwp().add(i.getManufacture().getGwp()).add(i.getPro_transport().getGwp()).add(i.getPro_recycle().getGwp());
            BigDecimal ap = i.getRaw().getAp().add(i.getManufacture().getAp()).add(i.getPro_transport().getAp()).add(i.getPro_recycle().getAp());
            BigDecimal ep = i.getRaw().getEp().add(i.getManufacture().getEp()).add(i.getPro_transport().getEp()).add(i.getPro_recycle().getEp());
            BigDecimal pocp = i.getRaw().getPocp().add(i.getManufacture().getPocp()).add(i.getPro_transport().getPocp()).add(i.getPro_recycle().getPocp());
            BigDecimal odp = i.getRaw().getOdp().add(i.getManufacture().getOdp()).add(i.getPro_transport().getOdp()).add(i.getPro_recycle().getOdp());
            BigDecimal sum = ped.add(gwp).add(ap).add(ep).add(pocp).add(odp);
            queue.add(new SortGraphVO(i, sum));
        }

        sorted=new ArrayList<>();
        int num=1;
        while(!queue.isEmpty()){
            if(num>=20) break;
            sorted.add(queue.poll().graphVO);
            num++;
        }


        for (PartGraphVO i : sorted) {

            partGraphVO2.getName().add(i.getName());

            //计算不同阶段的影响总和
            BigDecimal ped = i.getRaw().getPed().add(i.getManufacture().getPed()).add(i.getPro_transport().getPed()).add(i.getPro_recycle().getPed());
            BigDecimal gwp = i.getRaw().getGwp().add(i.getManufacture().getGwp()).add(i.getPro_transport().getGwp()).add(i.getPro_recycle().getGwp());
            BigDecimal ap = i.getRaw().getAp().add(i.getManufacture().getAp()).add(i.getPro_transport().getAp()).add(i.getPro_recycle().getAp());
            BigDecimal ep = i.getRaw().getEp().add(i.getManufacture().getEp()).add(i.getPro_transport().getEp()).add(i.getPro_recycle().getEp());
            BigDecimal pocp = i.getRaw().getPocp().add(i.getManufacture().getPocp()).add(i.getPro_transport().getPocp()).add(i.getPro_recycle().getPocp());
            BigDecimal odp = i.getRaw().getOdp().add(i.getManufacture().getOdp()).add(i.getPro_transport().getOdp()).add(i.getPro_recycle().getOdp());

            partGraphVO2.getData1().add(ped);
            partGraphVO2.getData2().add(gwp);
            partGraphVO2.getData3().add(ap);
            partGraphVO2.getData4().add(ep);
            partGraphVO2.getData5().add(pocp);
            partGraphVO2.getData6().add(odp);
        }

        return partGraphVO2;

    }

    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    class SortGraphVO {
        PartGraphVO graphVO;
        BigDecimal value;
    }


    private String getParent(String order) {
        if (order == null || order.length() == 0) {
            return "";
        }

        int length = order.split("\\.").length;
        if (length <= 1) return null;
        int end = order.length();
        for (int i = order.length() - 1; i >= 0; i--) {
            if (order.charAt(i) == '.') {
                end = i;
                break;
            }
        }
        return order.substring(0, end);
    }


}
